/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package genericos;

import basedatos.Pool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Clase que realiza la insercion a la base de datos usando nodos de insercion
 * asociados a una lista de nodos. Su metodo principal es insertanuevo que
 * realiza una insercion de datos en base a un arreglo de Insernodos y el nombre
 * de la tabla a realizar la insercion.
 *
 * @author Fernando Ramírez Martínez <Servicios Disaster Recovery>
 * @version 1.0
 * @see ListaNodos
 * @see Insernodo
 */
public class Insercion {

    Insernodo valor[];
    String sql = "";
    
   // static String url = "jdbc:mysql://localhost:3306/";
   // static String dbName = "zianya";
   // static String driver = "com.mysql.jdbc.Driver";
   // static String[] userpass = Conexion.userpass();
    private int id;
    Pool p=new Pool();
    /**
     * Metodo publico de la clase que realiza la insercion.
     *
     * Logica: Se obtiene el arreglo de Insernodos junto al nombre de la tabla.
     * La sentencia insert se forma con el nombre ed la tabla y de procede a
     * almacenar en la clase el valor del arreglo. Se apoya de dos métodos mas
     * que son formasentencia y formaincognitas y por ultimo uno de nombre
     * insercion.
     *
     * @param array Arreglo de Insernodos par realizar la insercion.
     * @param tabla nombre de la tabla sujeta a insercion.
     */
    public void insertanuevo(Insernodo[] array, String tabla) {
        valor = array;
        sql = "INSERT INTO " + tabla + " (";
        formasentencia();
        insercion();
    }

    /**
     * Metodo privado que permite formar la sentencia sql tomando el cuenta los
     * valores del arreglo.
     */
    private void formasentencia() {
        for (int i = 0; i < valor.length; i++) {

            if (i + 1 == valor.length) {
                sql = sql + valor[i].getCampo();
                formaincognitas();
            } else {
                sql = sql + valor[i].getCampo() + ",";
            }
        }

    }

    /**
     * Metodo privado que forma de modo complementario las incognitas para las
     * sentencias del insert.
     */
    private void formaincognitas() {
        sql = sql + ") values (";
        for (int i = 0; i < valor.length; i++) {

            if (i + 1 == valor.length) {
                sql = sql + "?);";
            } else {
                sql = sql + "?,";
            }
        }

    }

    /**
     * Metodo privado que realiza la conexion a la base de datos apoyandose de
     * un metodo de eleccion. Este metodo realiza la comunicacion e insercion
     * con la base de datos.
     */
    private void insercion() {
        PreparedStatement pst = null;
        Connection conn = null;
        try {
            conn = p.extraerConexion();
            pst = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
            pst = eleccion(pst);
            pst.executeUpdate();
            ResultSet res = pst.getGeneratedKeys();
            res.next();
            id = res.getInt(1);
            System.out.println("Registro insertado con exito");
        } catch (SQLException ex) {
            System.out.println(ex);;
        } finally {
            if (pst != null) {
                try {
                    pst.close();
                } catch (SQLException ex) {
                    System.out.println(ex);;
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    System.out.println(ex);;
                }
            }
        }
    }

    /**
     * Metodo privado que retorna un PreparedStatement qe ya tiene los valores
     * completos de la sentencia a elaborar en la insercion. Usa las cetegorias
     * del insernodo para disernir los tipos de datos a insertarse.
     *
     * @param pst PreparedStatement a modificar.
     * @return el mismo pero con los valores que han de ser insertados
     * posteriormente.
     */
    private PreparedStatement eleccion(PreparedStatement pst) {
        try {
            for (int i = 0; i < valor.length; i++) {
                if (valor[i].getCat() == 3) {
                    pst.setString(i + 1, valor[i].getValors());
                }
                if (valor[i].getCat() == 1) {

                    pst.setInt(i + 1, valor[i].getValorin());
                }
                if (valor[i].getCat() == 2) {
                    pst.setDate(i + 1, valor[i].getValordo());
                }
                if (valor[i].getCat() == 4) {
                    pst.setDouble(i + 1, valor[i].getX());
                }

            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return pst;

    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }
}
